package com.vhans.db.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vhans.core.domain.CFriend;
import com.vhans.core.domain.CMsg;
import com.vhans.core.utils.BeanCopyUtils;
import com.vhans.core.utils.SpringUtils;
import com.vhans.core.utils.StringUtils;
import com.vhans.db.mapper.BUserMapper;
import com.vhans.db.mapper.CFriendMapper;
import com.vhans.db.mapper.CMsgMapper;
import com.vhans.db.model.dto.ConditionDTO;
import com.vhans.db.model.dto.friend.FriendDTO;
import com.vhans.db.model.vo.friend.FriendInfoVO;
import com.vhans.db.model.vo.friend.FriendListVO;
import com.vhans.db.model.vo.friend.FriendVO;
import com.vhans.db.model.vo.friend.SingleRecentConversationResultVo;
import com.vhans.db.model.vo.msg.MsgLastVO;
import com.vhans.db.service.ICFriendService;
import com.vhans.db.service.ICMsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 好友Service业务层处理
 *
 * @author vhans
 * @date 2023-05-21
 */
@Service("cFriendServiceImpl")
public class CFriendServiceImpl implements ICFriendService {
    @Autowired
    private CFriendMapper friendMapper;

    @Autowired
    private CMsgMapper msgMapper;

    @Autowired
    private BUserMapper userMapper;

    @Autowired
    private ICMsgService msgService;

    @Override
    public List<FriendVO> selectCFriendVOList(ConditionDTO condition) {
        // 查询好友信息
        return friendMapper.selectFriendVOList(condition);
    }

    @Override
    public List<FriendListVO> selectUserFriendVOList() {
        int userId = StpUtil.getLoginIdAsInt();
        return friendMapper.selectMFriendVOListByUserId(userId);
    }

    @Override
    public List<SingleRecentConversationResultVo> getRecentConversation(FriendDTO friendDTO) {
        // 获取基本消息(房间号,备注,头像)
        List<SingleRecentConversationResultVo> singleRecentConversationResultVos = friendMapper.selectRecentConversation(friendDTO);
        singleRecentConversationResultVos.forEach(item -> {
            // 封装最近好友会话
            // roomId反向,我现在是接收方
            String[] roomIds = item.getRoomId().split("_");
            String newRoomId = roomIds[1] + "_" + roomIds[0];
            MsgLastVO lastMsg = msgService.getLastMsg(newRoomId);
            Integer unread = msgMapper.getUnread(newRoomId);
            if (lastMsg.getMsgType() == 1) {
                item.setLastMsg(lastMsg.getContent());
            } else {
                item.setLastMsg(lastMsg.getMsgType() == 2 ? "[图片]" :
                        (lastMsg.getMsgType() == 3 ? "[视频]" : "[语音]"));
            }
            if (StringUtils.isNotNull(lastMsg.getCreateTime())) {
                item.setTime(lastMsg.getCreateTime());
            }
            item.setUnread(unread > 99 ? 99 : unread);
        });
        return singleRecentConversationResultVos;
    }

    @Override
    @Transactional
    public void insertFriend(FriendDTO friend) {
        CFriend friendTmp = friendMapper.selectOne(new LambdaQueryWrapper<CFriend>()
                .select(CFriend::getId)
                .eq(CFriend::getUserId, friend.getUserId())
                .eq(CFriend::getFriendId, friend.getFriendId()));
        Assert.isTrue(StringUtils.isNull(friendTmp), "已添加好友");
        // 添加好友
        CFriend newFriend = BeanCopyUtils.copyBean(friend, CFriend.class);
        friendMapper.insert(newFriend);
        // 反向再添加一次
        // 默认好友备注为好友昵称
        String nickname = userMapper.selectById(friend.getUserId()).getNickname();
        friendMapper.insert(CFriend.builder()
                .friendRemark(nickname)
                .userId(newFriend.getFriendId())
                .friendId(newFriend.getUserId()).build());
    }

    @Override
    public FriendInfoVO selectCFriendInfoById(Integer id) {
        // 查询好友信息
        FriendInfoVO cFriendInfoVO = friendMapper.selectFriendInfoById(id);
        Assert.notNull(cFriendInfoVO, "没有该好友");
        // 下面可以扩展信息delete
        return cFriendInfoVO;
    }

    @Override
    public int updateCFriend(FriendDTO cFriend) {
        // 要修改的好友
        CFriend newCFriend = BeanCopyUtils.copyBean(cFriend, CFriend.class);
        // 这里可以设置额外信息delete

        return friendMapper.updateById(newCFriend);
    }

    @Override
    @Transactional
    public int deleteFriend(FriendDTO friend) {
        // 当前用户id
        int userId = StpUtil.getLoginIdAsInt();
        Assert.isTrue(Objects.equals(userId, friend.getUserId()), "用户不一致,禁止删除");
        // 默认UserId是主动删除者的ID，FriendId是被动删除者的ID
        int row = friendMapper.delete(new LambdaQueryWrapper<CFriend>()
                .eq(CFriend::getUserId, friend.getUserId())
                .eq(CFriend::getFriendId, friend.getFriendId())
                .or()
                .eq(CFriend::getUserId, friend.getFriendId())
                .eq(CFriend::getFriendId, friend.getUserId()));
        delSingleHistoryMessage(friend.getRoomId());
        return row;
    }

    /**
     * 根据 roomId 删除两者的聊天记录
     *
     * @param roomId 房间号 (mId_yId)
     */
    private void delSingleHistoryMessage(String roomId) {
        String[] ids = roomId.split("_");
        String ymRoomId = ids[0] + '_' + ids[1];
        // 正反信息均删除
        msgMapper.delete(new LambdaQueryWrapper<CMsg>()
                .eq(CMsg::getRoomId, roomId)
                .or()
                .eq(CMsg::getRoomId, ymRoomId));
    }
}
